Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

Ищу совета по оптимизации SQL-запроса (amixen)
Author Message
amixen
Участник форума



Joined: 04 Jul 2005
Posts: 32
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 27, 2006 7:40 pm (написано за 10 минут 4 секунды)
   Post subject: Ищу совета по оптимизации SQL-запроса
Reply with quote

Использую PHP + MySql.
Задался я целью написать движок с поддержкой большого числа языков. Придумал так что, например если речь идет о менюшке, в одну табу пишется URL и ID, а в другую - несколько записей(для каждого языка своя).
Code (SQL): скопировать код в буфер обмена
CREATE TABLE `menu` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `url` varchar(255) NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=3 ;
INSERT INTO `menu` VALUES (1, '?post=fb');
INSERT INTO `menu` VALUES (2, '?post=map');
CREATE TABLE `menu_lang` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `field_id` int(11) NOT NULL DEFAULT '0',
  `lang_bit` int(11) NOT NULL DEFAULT '0',
  `text` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=7 ;
INSERT INTO `menu_lang` VALUES (1, 1, 1, ' ');
INSERT INTO `menu_lang` VALUES (2, 1, 2, 'FeedBack');
INSERT INTO `menu_lang` VALUES (3, 1, 4, ' ''');
INSERT INTO `menu_lang` VALUES (4, 2, 1, ' ');
INSERT INTO `menu_lang` VALUES (5, 2, 2, 'Site map');
INSERT INTO `menu_lang` VALUES (6, 2, 4, ' ');
Если хочу вытащить пункт менюшки на всех языках (например для редактирования) то делаю это запросом:
Code (SQL): скопировать код в буфер обмена
SELECT t.id, t.url, k.lang_bit, k.text
FROM menu AS t
LEFT JOIN menu_lang AS k ON k.field_id = t.id
WHERE t.id IS NOT NULL AND t.id='1'
ORDER BY k.lang_bit, k.text
Ко мне приходят три найдех строки:
id ---- url -- lang_bit -- text
1 --- ?post=fb --- 1 --- Обратная связь
1 --- ?post=fb --- 2 --- FeedBack
1 --- ?post=fb --- 4 --- Зворотній зв'язок

Потом мне приходится проходить циклом, что привести это к виду массива, что не есть правильно.
Лишние итерации и на быстродействие влияют вцелом...

У меня вопрос к аудитории: Можно ли что сделать с запросом, что бы результат SQL-запроса была одна строка?

Last edited by amixen on Tue Jun 27, 2006 10:14 pm; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
Andrey Gurin
Участник форума



Joined: 24 May 2005
Posts: 183
Карма: 20
   поощрить/наказать

Location: Italy

PostPosted: Tue Jun 27, 2006 10:05 pm (спустя 2 часа 25 минут; написано за 2 минуты 4 секунды)
   Post subject:
Reply with quote

Попробуйте так
Code (SQL): скопировать код в буфер обмена
SELECT ... GROUP_CONCAT(k.text SEPARATOR '|')
...
GROUP BY t.id
dev.mysql.com/doc/refman/5.1/en/group-by-functions.html
Back to top
View user's profile Send private message
amixen
Участник форума



Joined: 04 Jul 2005
Posts: 32
Карма: 0
   поощрить/наказать


PostPosted: Tue Jun 27, 2006 10:13 pm (спустя 7 минут; написано за 30 секунд)
   Post subject:
Reply with quote

Andrey Gurin wrote:
GROUP_CONCAT(k.text SEPARATOR '|')
Прошу прощения, я стормозил...
Имеется ввиду MySql
Back to top
View user's profile Send private message Send e-mail
Andrey Gurin
Участник форума



Joined: 24 May 2005
Posts: 183
Карма: 20
   поощрить/наказать

Location: Italy

PostPosted: Tue Jun 27, 2006 10:15 pm (спустя 2 минуты; написано за 19 секунд)
   Post subject:
Reply with quote

Я тоже о нем говорил
Back to top
View user's profile Send private message
amixen
Участник форума



Joined: 04 Jul 2005
Posts: 32
Карма: 0
   поощрить/наказать


PostPosted: Wed Jun 28, 2006 4:01 pm (спустя 17 часов 46 минут; написано за 2 минуты 15 секунд)
   Post subject:
Reply with quote

Andrey Gurin wrote:
GROUP_CONCAT
Вариант неплохой, но ограничен версией мускуля 5.1**, к сожалению. А если есть проекты написанные под MySql 4.1**?

К тому же если нету на одном из языков, то этот язык не находится ессесно, а как тогда узнать какие языки нашлись а какие нет?

Last edited by amixen on Thu Jun 29, 2006 2:41 pm; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
amixen
Участник форума



Joined: 04 Jul 2005
Posts: 32
Карма: 0
   поощрить/наказать


PostPosted: Wed Jun 28, 2006 4:09 pm (спустя 7 минут; написано за 4 минуты 3 секунды)
   Post subject:
Reply with quote

Вот родился промежуточный вариант:
Code (SQL): скопировать код в буфер обмена
SELECT t.id, t.url, k.lang_bit, k.text,
(SELECT `text` FROM menu_lang WHERE field_id = '1' AND lang_bit = '1') AS text_1, (SELECT `text` FROM menu_lang WHERE field_id = '1' AND lang_bit = '2') AS text_2, (SELECT `text` FROM menu_lang WHERE field_id = '1' AND lang_bit = '4') AS text_4
FROM menu AS t
LEFT JOIN menu_lang AS k ON k.field_id = t.id
WHERE t.id IS NOT NULL
GROUP BY k.field_id
ORDER BY t.id, k.lang_bit, k.text
Результат:
id ----- url ---- lang_bit ------- text ----------- text_1 ------- text_2 -------- text_4
1 --- ?post=fb ---- 1 ------ Обратная связь --- Обратная связь -- FeedBack ----- Зворотній зв'язок
2 --- ?post=map --- 1 ------ Карта сайта ------ Обратная связь -- FeedBack ----- Зворотній зв'язок

Минус - временные ресурсы. Отработка занимает 0.0073 сек, для этой базы нормально, а вот для большой базы, да если еще сортировка чуть построже, то могут быть секунды... А это не правильно :-(

Есть еще идеи?
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
You cannot post new topics in this forum. You cannot reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML